package com.canaan.business.controller.pc.bill;

import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.List;

import cn.hutool.core.collection.CollectionUtil;
import cn.hutool.core.lang.Pair;
import cn.hutool.json.JSONUtil;
import com.canaan.business.common.enums.inOutStock.BillBindOperationEnum;
import com.canaan.business.common.enums.inOutStock.ErpBillTypeEnum;
import com.canaan.business.common.enums.inOutStock.InOrderStatusEnum;
import com.canaan.business.domain.bill.*;
import com.canaan.business.domain.vo.*;
import com.canaan.business.service.bill.*;
import com.canaan.common.encrypt.PushEdiService;
import com.canaan.common.utils.DateUtils;
import com.canaan.system.service.ISysConfigService;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import javax.servlet.http.HttpServletResponse;
import org.springframework.security.access.prepost.PreAuthorize;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.PutMapping;
import org.springframework.web.bind.annotation.DeleteMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;
import com.canaan.common.annotation.Log;
import com.canaan.common.core.controller.BaseController;
import com.canaan.common.core.domain.AjaxResult;
import com.canaan.common.enums.BusinessType;
import javax.annotation.Resource;

import com.canaan.common.utils.poi.ExcelUtil;
import com.canaan.common.core.page.TableDataInfo;

/**
 * 入库调整单Controller
 *
 * @author canaan
 * @date 2025-03-24
 */
@Api(tags = "入库调整单")
@RestController
@RequestMapping("/bill/modulationInBill")
public class ModulationInBillController extends BaseController {
    @Resource
    private IModulationInBillService modulationInBillService;
    @Resource
    private IModulationInBillDetailService modulationInBillDetailService;
    @Resource
    private ISysConfigService sysConfigService;
    @Resource
    private IBillDetailRecordService billDetailRecordService;
    @Resource
    private ITrayService trayService;
    @Resource
    private ITrayDetailService trayDetailService;
    @Resource
    private IAdjustInBillService adjustInBillService;
    /**
     * 查询入库调整单列表
     */
    @ApiOperation(value = "查询入库调整单列表")
//    @PreAuthorize("@ss.hasPermi('bill:modulationInBill:list')")
    @GetMapping("/list")
    public TableDataInfo list(ModulationInBill modulationInBill) {
        startPage();
        List<ModulationInBill> list = modulationInBillService.selectModulationInBillList(modulationInBill);
        return getDataTable(list);
    }

    /**
     * 导出入库调整单列表
     */
    @ApiOperation(value = "导出入库调整单列表")
    @PreAuthorize("@ss.hasPermi('bill:modulationInBill:export')")
    @Log(title = "入库调整单", businessType = BusinessType.EXPORT)
    @PostMapping("/export")
    public void export(HttpServletResponse response, ModulationInBill modulationInBill) {
        List<ModulationInBill> list = modulationInBillService.selectModulationInBillList(modulationInBill);
        ExcelUtil<ModulationInBill> util = new ExcelUtil<ModulationInBill>(ModulationInBill.class);
        util.exportExcel(response, list, "入库调整单数据");
    }

    /**
     * 获取入库调整单详细信息
     */
    @ApiOperation(value = "获取入库调整单详细信息")
//    @PreAuthorize("@ss.hasPermi('bill:modulationInBill:query')")
    @GetMapping(value = "/{id}")
    public AjaxResult getInfo(@PathVariable("id") Long id) {
        return success(modulationInBillService.selectModulationInBillById(id));
    }

    /**
     * 新增入库调整单
     */
    @ApiOperation(value = "新增入库调整单")
    @PreAuthorize("@ss.hasPermi('bill:modulationInBill:add')")
    @Log(title = "入库调整单", businessType = BusinessType.INSERT)
    @PostMapping
    public AjaxResult add(@RequestBody ModulationInBill modulationInBill) {
        return toAjax(modulationInBillService.insertModulationInBill(modulationInBill));
    }

    /**
     * 修改入库调整单
     */
    @ApiOperation(value = "修改入库调整单")
    @PreAuthorize("@ss.hasPermi('bill:modulationInBill:edit')")
    @Log(title = "入库调整单", businessType = BusinessType.UPDATE)
    @PutMapping
    public AjaxResult edit(@RequestBody ModulationInBill modulationInBill) {
        return toAjax(modulationInBillService.updateModulationInBill(modulationInBill));
    }

    /**
     * 删除入库调整单
     */
    @ApiOperation(value = "删除入库调整单")
    @PreAuthorize("@ss.hasPermi('bill:modulationInBill:remove')")
    @Log(title = "入库调整单", businessType = BusinessType.DELETE)
	@DeleteMapping("/{ids}")
    public AjaxResult remove(@PathVariable Long[] ids) {
        return toAjax(modulationInBillService.deleteModulationInBillByIds(ids));
    }
    @ApiOperation(value = "完成收货")
    @Log(title = "完成收货", businessType = BusinessType.UPDATE)
    @PostMapping("/complete")
    public AjaxResult complete(@RequestBody ModulationInBill modulationInBill){
        ModulationInBill bill=modulationInBillService.selectModulationInBillByNo(modulationInBill.getBizNo());
        if(bill==null){
            return error("出库调整单"+bill.getBizNo()+"不存在");
        }
        bill.setStatus(InOrderStatusEnum.ACCOMPLISH.getCode());
        bill.setCompleteTime(DateUtils.getNowDate());
        adjustInBillService.postInStockCallback(bill.getBizNo(),bill.getStockStatus());
        int result = modulationInBillService.updateModulationInBill(bill);
        return toAjax(result);
    }

    /**
     * 入库回调
     * @param bill 采购入库单
     */
    private void postInStockCallback(ModulationInBill bill){
        InStockCallbackVo inStockCallbackVo = new InStockCallbackVo();
        inStockCallbackVo.setBizNo(bill.getBizNo());
        inStockCallbackVo.setWmsBizNo(bill.getBizNo());
        ModulationInBillDetail query=new ModulationInBillDetail();
        query.setBizNo(bill.getBizNo());
        List<ModulationInBillDetail> details=modulationInBillDetailService.selectModulationInBillDetailList(query);
        List<GoodsVo> goodsVos=new ArrayList<>();
        for (ModulationInBillDetail item : details){
            GoodsVo goodsVo=new GoodsVo();
            goodsVo.setBatchNo(item.getBatchNo());
            goodsVo.setCode(item.getProductNo());
            goodsVo.setUnit(item.getProductUnit());
            goodsVo.setNum(item.getQty().toString());
            goodsVo.setStatus(Integer.parseInt(bill.getStockStatus()));
            goodsVos.add(goodsVo);
        }
        inStockCallbackVo.setGoodDetails(goodsVos);
        SimpleDateFormat simpleDateFormat=new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
        inStockCallbackVo.setDeliveryDate(simpleDateFormat.format(DateUtils.getNowDate()));

        // 发送入库回调
        if(Boolean.parseBoolean(sysConfigService.selectConfigByKey("edi.swtich"))){
            Pair<Boolean, String> result= PushEdiService.push(sysConfigService.selectConfigByKey("edi.inner"), JSONUtil.toJsonStr(inStockCallbackVo));
            System.out.println("post = " + result.getValue());
            if(!result.getKey()){
                throw new RuntimeException(result.getValue());
            }
        }
    }
    /**
     * 收货
     */
    @ApiOperation(value = "收货")
    @Log(title = "收货", businessType = BusinessType.UPDATE)
    @PostMapping("/addDetail")
    @Transactional
    public AjaxResult addDetail(@RequestBody ModulationInDetailVo modulationInDetailVo){
        if(modulationInDetailVo.getProductDate()==null){
            return error("生产日期不能为空");
        }
        int result= addAdjustInBillDetail(modulationInDetailVo)?1:0;
        return toAjax(result);
    }

    /**
     * 添加收货明细
     * @param modulationInDetailVo 收货明细
     * @return
     */
    private boolean addAdjustInBillDetail(ModulationInDetailVo modulationInDetailVo){
        //更新明细数量
        ModulationInBillDetail query=new ModulationInBillDetail();
        query.setBizNo(modulationInDetailVo.getBizNo());
        query.setProductNo(modulationInDetailVo.getProductNo());
        query.setDelFlag("0");

        TrayDetail trDetail = new TrayDetail();
        trDetail.setTrayNo(modulationInDetailVo.getTrayNo());
        List<TrayDetail> trayDetails =  trayDetailService.selectTrayDetailList(trDetail);
        if (CollectionUtil.isNotEmpty(trayDetails)) {
            //一个托盘只能放一种物料和一个批次
            throw new RuntimeException("托盘" + modulationInDetailVo.getTrayNo() + "已经存在物料" + trayDetails.get(0).getProductNo());
        }

        ModulationInBill modulationInBill=modulationInBillService.selectModulationInBillByNo(modulationInDetailVo.getBizNo());
        if (modulationInBill==null){
            throw new RuntimeException("收货调整单"+modulationInDetailVo.getBizNo()+"不存在");
        }
        if(modulationInBill.getCheckTotalQty()+modulationInDetailVo.getQty()>modulationInBill.getTotalQty()){
            throw new RuntimeException("收货调整单"+modulationInDetailVo.getBizNo()+"收货总数超过"+modulationInBill.getTotalQty());
        }
        modulationInBill.setCheckTotalQty(modulationInBill.getCheckTotalQty()+modulationInDetailVo.getQty());
        modulationInBill.setStatus(InOrderStatusEnum.PICKING.getCode());
        modulationInBillService.updateModulationInBill(modulationInBill);

        List<ModulationInBillDetail> modulationInBillDetails=modulationInBillDetailService.selectModulationInBillDetailList(query);
        if(modulationInBillDetails==null||modulationInBillDetails.size()==0){
            throw new RuntimeException(modulationInDetailVo.getBizNo()+"不存在物料"+modulationInDetailVo.getProductNo()+"明细");
        }
        ModulationInBillDetail modulationInBillDetail=modulationInBillDetails.get(0);
        if(modulationInBillDetail.getReceivedQty()+modulationInDetailVo.getQty()>modulationInBillDetail.getQty()){
            throw new RuntimeException(modulationInDetailVo.getBizNo()+"不存在物料"+modulationInDetailVo.getProductNo()+"明细超出数量"+modulationInBillDetail.getQty());
        }
        //增加单据明细
        BillDetailRecord billDetailRecord=new BillDetailRecord();
        billDetailRecord.setBillNo(modulationInDetailVo.getBizNo());
        billDetailRecord.setTrayNo(modulationInDetailVo.getTrayNo());
        billDetailRecord.setBillType(ErpBillTypeEnum.ADJUST_IN.getCode());
        billDetailRecord.setProductNo(modulationInDetailVo.getProductNo());
        billDetailRecord.setProductName(modulationInDetailVo.getProductName());
        billDetailRecord.setBatchNo(modulationInDetailVo.getBatchNo());
        billDetailRecord.setQty(modulationInDetailVo.getQty());
        billDetailRecord.setProductUnit(modulationInDetailVo.getProductUnit());
        billDetailRecord.setOperation(BillBindOperationEnum.ADJUST_IN.getMessage());
        billDetailRecord.setStockStatus(modulationInBill.getStockStatus());
        billDetailRecord.setProductionDate(DateUtils.parseDateToStr(DateUtils.YYYY_MM_DD,modulationInDetailVo.getProductDate()));
        billDetailRecord.setExpiryDate(DateUtils.parseDateToStr(DateUtils.YYYY_MM_DD,modulationInDetailVo.getValidDate()));
        billDetailRecordService.insertBillDetailRecord(billDetailRecord);
        //修改对应的明细表批次号,返回给EDI时需要用到
        modulationInBillDetail.setBatchNo(modulationInDetailVo.getBatchNo());
        modulationInBillDetail.setReceivedQty(modulationInBillDetail.getReceivedQty()+modulationInDetailVo.getQty());
        modulationInBillDetailService.updateModulationInBillDetail(modulationInBillDetail);
        //增加托盘
        Tray tray=trayService.selectTrayByTrayNo(modulationInDetailVo.getTrayNo());
        if(tray==null){
            tray=new Tray();
            tray.setErpInBillNo(modulationInBill.getBizNo());
            tray.setStockStatus(modulationInBill.getStockStatus());
            tray.setTrayNo(modulationInDetailVo.getTrayNo());
            tray.setOwner(modulationInBill.getOwner());
            tray.setStockCode(modulationInBill.getStockCode());
            trayService.insertTray(tray);
        }
        else{
            tray.setErpInBillNo(modulationInBill.getBizNo());
            tray.setStockStatus(modulationInBill.getStockStatus());
            tray.setErpOutBillNo("");
            tray.setSplitBillNo("");
            tray.setOutBillNo("");
            tray.setInBillNo("");
            tray.setOwner(modulationInBill.getOwner());
            tray.setStockCode(modulationInBill.getStockCode());
            trayService.updateTray(tray);
        }
        //增加托盘明细
        TrayDetail trayDetailQuery=new TrayDetail();
        trayDetailQuery.setTrayNo(modulationInDetailVo.getTrayNo());
        trayDetailQuery.setProductNo(modulationInDetailVo.getProductNo());
        trayDetailQuery.setDelFlag("0");
        List<TrayDetail> trayResults=trayDetailService.selectTrayDetailList(trayDetailQuery);
        if(trayResults!=null&&trayResults.size()!=0){
            throw new RuntimeException("托盘"+modulationInDetailVo.getTrayNo()+"已经存在物料"+modulationInDetailVo.getProductNo()+"明细");
        }
        TrayDetail trayDetail =new TrayDetail();
        trayDetail.setTrayNo(modulationInDetailVo.getTrayNo());
        trayDetail.setProductName(modulationInDetailVo.getProductName());
        trayDetail.setProductNo(modulationInDetailVo.getProductNo());
        trayDetail.setProductUnit(modulationInDetailVo.getProductUnit());
        trayDetail.setBatchNo(modulationInDetailVo.getBatchNo());
        trayDetail.setStockStatus(modulationInBill.getStockStatus());
        trayDetail.setQty(modulationInDetailVo.getQty());
        trayDetail.setProductionDate(modulationInDetailVo.getProductDate());
        if(modulationInDetailVo.getProductDate()!=null&&modulationInDetailVo.getValidDate()!=null){
            trayDetail.setValidDateNum(DateUtils.differentDaysByMillisecond(modulationInDetailVo.getValidDate(), modulationInDetailVo.getProductDate()));
        }
        trayDetailService.insertTrayDetail(trayDetail);
        return  true;
    }
    /**
     * 确定
     */
    @ApiOperation(value = "删除明细")
    @Log(title = "删除明细", businessType = BusinessType.UPDATE)
    @PostMapping("/deleteDetail")
    public AjaxResult deleteDetail(@RequestBody ModulationInDetailVo detailVo){
        int result= deleteModulationInBillDetail(detailVo)?1:0;
        return toAjax(result);
    }
    /**
     * 删除明细
     * @param detailVo
     * @return
     */
    @Transactional
    public boolean deleteModulationInBillDetail(ModulationInDetailVo detailVo){
        //更新明细数量
        ModulationInBillDetail query=new ModulationInBillDetail();
        query.setBizNo(detailVo.getBizNo());
        query.setProductNo(detailVo.getProductNo());
        query.setDelFlag("0");

        ModulationInBill modulationInBill =modulationInBillService.selectModulationInBillByNo(detailVo.getBizNo());
        if (modulationInBill ==null){
            throw new RuntimeException("入库调整单"+detailVo.getBizNo()+"不存在");
        }
        if(modulationInBill.getCheckTotalQty()-detailVo.getQty()<0){
            modulationInBill.setCheckTotalQty(0l);
        }
        else {
            modulationInBill.setCheckTotalQty(modulationInBill.getCheckTotalQty() - detailVo.getQty());
        }
        modulationInBillService.updateModulationInBill(modulationInBill);

        List<ModulationInBillDetail> modulationInBillDetails =modulationInBillDetailService.selectModulationInBillDetailList(query);
        if(modulationInBillDetails ==null|| modulationInBillDetails.size()==0){
            throw new RuntimeException("调拨入库单"+detailVo.getBizNo()+"不存在物料"+detailVo.getProductNo()+"明细");
        }
        ModulationInBillDetail modulationInBillDetail= modulationInBillDetails.get(0);
        if(modulationInBillDetail.getReceivedQty()-detailVo.getQty()<0){
            modulationInBillDetail.setReceivedQty(0l);
        }
        else{
            modulationInBillDetail.setReceivedQty(modulationInBillDetail.getReceivedQty()-detailVo.getQty());
        }
        modulationInBillDetailService.updateModulationInBillDetail(modulationInBillDetail);
        //增加单据明细
        BillDetailRecord billDetailQuery=new BillDetailRecord();
        billDetailQuery.setBillNo(detailVo.getBizNo());
        billDetailQuery.setTrayNo(detailVo.getTrayNo());
        billDetailQuery.setProductNo(detailVo.getProductNo());
        billDetailQuery.setDelFlag("0");
        List<BillDetailRecord> billDetailRecords=billDetailRecordService.selectBillDetailRecordList(billDetailQuery);
        if(billDetailRecords==null||billDetailRecords.size()==0){
            throw new RuntimeException(detailVo.getBizNo()+"单据明细中不存在托盘"+detailVo.getTrayNo()+"物料"+detailVo.getProductNo());
        }
        BillDetailRecord record=billDetailRecords.get(0);
        billDetailRecordService.deleteBillDetailRecordById(record.getId());
        //增加托盘明细
        TrayDetail trayDetailQuery =new TrayDetail();
        trayDetailQuery.setTrayNo(detailVo.getTrayNo());
        trayDetailQuery.setProductNo(detailVo.getProductNo());
        trayDetailQuery.setDelFlag("0");
        List<TrayDetail> trayDetails=trayDetailService.selectTrayDetailList(trayDetailQuery);
        if(trayDetails==null||trayDetails.size()==0){
            throw new RuntimeException("托盘"+detailVo.getTrayNo()+"明细中不存在物料"+detailVo.getProductNo());
        }
        TrayDetail trayDetail=trayDetails.get(0);
        trayDetailService.deleteTrayDetailById(trayDetail.getId());
        return  true;
    }


    /**
     * 订单打印
     */
    @ApiOperation(value = "订单打印")
    @Log(title = "订单打印", businessType = BusinessType.EXPORT)
    @GetMapping("/selectModulationInBillForPrint")
    public AjaxResult selectModulationInBillForPrint(@RequestParam("no") String no) {
        return success(modulationInBillService.selectModulationInBillForPrint(no));
    }
}
